package org.hyl.javabase.反射;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;

public class demo {
	public static void main(String[] arg) {
		demo d = new demo();
		// d.fun1();
		// d.fun2();
	

		// d.fun2_1();
		//d.fun2_2();
		//d.fun3_1() ;
		// d.fun3_2();
		//d.fun3_3();
		//d.fun3_4();
		// d.fun4();
		// d.fun4_1();
		// d.fun4_2();
		// d.fun5();
		// d.fun5_1();
		 d.fun5_2();
		// d.fun6();
		// d.fun6_1();
	}

	public void fun1() {
		Class<?> class1 = null;
		Class<?> class2 = null;
		Class<?> class3 = null;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			class2 = new student().getClass();
			class3 = student.class;
			System.out.println("类名称   " + class1.getName());
			System.out.println("类名称   " + class2.getName());
			System.out.println("类名称   " + class3.getName());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void fun2() {

		Class<?> class1 = null;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			student user = (student) class1.newInstance();

			user.setName("Rollen");
			System.out.println(user);
			System.out.println(user.getName());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	public void fun2_1() {

		Class<?> class1 = null;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			Constructor<?> cons[] = class1.getConstructors();
			// 查看每个构造方法需要的参数
			for (int i = 0; i < cons.length; i++) {
				Class<?> clazzs[] = cons[i].getParameterTypes();
				System.out.print(class1.getName() + " cons[" + i + "] (");
				for (int j = 0; j < clazzs.length; j++) {
					if (j == clazzs.length - 1)
						System.out.print(clazzs[j].getName());
					else
						System.out.print(clazzs[j].getName() + ",");
				}
				System.out.println(")");
			}
			student s;
			s = (student) cons[1].newInstance("Rollen");
			System.out.println(s);

			s = (student) cons[0].newInstance("20", "Rollen");
			System.out.println(s);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	  public  void fun2_2() {

	        try {
	            
	            //创建类
	            Class<?> class1 = Class.forName("javabase.p201707020.student");

	            //无参构造函数
	            Object object = class1.newInstance() ;
	            System.out.println(object);
	            //有参构造函数：一个参数
	            Constructor<?> constructor =  class1.getDeclaredConstructor( String.class ) ;
	            Object object1 = constructor.newInstance( "xiao tao" ) ;
	            System.out.println(object1);
	            //有参构造函数：二个参数
	            Constructor<?> constructor2 =  class1.getDeclaredConstructor( String.class , String.class ) ;
	            Object object2 =constructor2.newInstance( "xiao gang" , "jack" ) ;
	            System.out.println(object2);
	        } catch (InstantiationException e) {
	            e.printStackTrace();
	        } catch (IllegalAccessException e) {
	            e.printStackTrace();
	        } catch (InvocationTargetException e) {
	            e.printStackTrace();
	        } catch (IllegalArgumentException e) {
	            e.printStackTrace();
	        } catch (NoSuchMethodException e) {
	            e.printStackTrace();
	        } catch (SecurityException e) {
	            e.printStackTrace() ;
	        } catch (ClassNotFoundException e) {
	            e.printStackTrace();
	        }

	    }
	public void fun4() {
		// 取得本类的全部属性
		Class<?> class1 = null;
		try {
			class1 = Class.forName("javabase.p201707020.student");

			Field[] field = class1.getDeclaredFields();
			for (int i = 0; i < field.length; i++) {
				// 权限修饰符
				int mo = field[i].getModifiers();
				String priv = Modifier.toString(mo);
				// 属性类型
				Class<?> type = field[i].getType();
				System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
				System.out.println("field.Modifier=" + priv + "; field.type=" + type.getName() + "; field.name="
						+ field[i].getName() + ";");
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void fun4_1() {
		Class<?> class1 = null;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			// 取得可见的属性
			Field[] filed1 = class1.getFields();
			for (int j = 0; j < filed1.length; j++) {
				// 权限修饰符
				int mo = filed1[j].getModifiers();
				String priv = Modifier.toString(mo);
				// 属性类型
				Class<?> type = filed1[j].getType();
				System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";");
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void fun4_2() {
		Class<?> class1 = null;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			// 取得可见的属性
			Method method[] = class1.getMethods();
			for (int i = 0; i < method.length; ++i) {
				Class<?> returnType = method[i].getReturnType();
				Class<?> para[] = method[i].getParameterTypes();
				Class<?> exce[] = method[i].getExceptionTypes();

				System.out.println(method[i].getName() + " ");
				System.out.println(" -修饰权限=" + Modifier.toString(method[i].getModifiers()) + " ");
				System.out.println(" -返回类型=" + returnType.getName() + "  ");
				if (para.length > 0) {
					System.out.print("(");
					for (int j = 0; j < para.length; ++j) {
						System.out.print("第" + j + "个参数 : " + para[j].getName() + " ");
						if (j < para.length - 1) {
							System.out.print(",");
						}
					}
					System.out.println(")  ");
				}

				if (exce.length > 0) {

					System.out.print("抛出异常：( ");
					for (int k = 0; k < exce.length; ++k) {
						System.out.print(exce[k].getName() + " ");
						if (k < exce.length - 1) {
							System.out.print(",");
						}
					}
					System.out.println("  )");
				}
				System.out.println();
			}

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}



	public void fun3_1() {

		Class<?> class1 = null;
		try {
			class1 = Class.forName("javabase.p201707020.student");

			Object o = class1.newInstance();// 调哟了的是默认的构造函数
			// Object o = class1.newInstance("pp");// 错误的
			// student o=(student)class1.newInstance();
			// Constructor<?> cons[] = class1.getConstructors();
			// student o=(student) cons[1].newInstance("xx");
			// Java 反射机制 - 调用某个类的方法
			Method getName = class1.getMethod("getName");
			getName.invoke(o);
	
			Method setName = class1.getMethod("setName", String.class);
			setName.invoke(o, "张三");

		} catch (Exception e) {

			e.printStackTrace();
		}
	}

	public void fun3_2() {
		Class<?> class1;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			Object obj = class1.newInstance();
			// 可以直接对 private 的属性赋值
			Field field = class1.getDeclaredField("pp");

			// 打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问
			// 由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
			field.setAccessible(true);
			field.set(obj, "Java反射机制");
			System.out.println(field.get(obj));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void fun3_3() {
		Class<?> class1;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			// Object obj = class1.newInstance();

			Method method = class1.getMethod("getNow");
			String result_2 = (String) method.invoke(null);
			System.out.println(result_2);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	public void fun3_4() {
		Class<?> class1;
		try {
			class1 = Class.forName("javabase.p201707020.student");
			// Object obj = class1.newInstance();
			//获取方法的时候需要用：int.class。不能使用 Integer.class. 会报错。
			Method Method4 = class1.getDeclaredMethod( "getInt" , int.class ) ; 
			String result_4 = (String) Method4.invoke( null  , 1 ) ;
			System.out.println( "返回值： "+ result_4 );
			//获取方法的时候需要用：Integer .class。不能使用 int.class. 会报错。
			Method Method5 = class1.getDeclaredMethod( "getInteger" , Integer.class ) ; 
			String result_5 = (String) Method5.invoke( null  , new Integer(12)) ;
			System.out.println( "返回值： "+ result_5 );


		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	

	// 在泛型为Integer的ArrayList中存放一个String类型的对象。
	public void fun5() {
		//class1 = Class.forName("javabase.p201707020.student");//
		ArrayList<Integer> list = new ArrayList<Integer>();
		Method method;
		try {
			// System.out.println(list.hashCode());
			list.add(2);
			//list.add("Java反射机制实例。");
			method = list.getClass().getMethod("add", Object.class);
			method.invoke(list, "Java反射机制实例。");
			System.out.println(list);
			System.out.println(list.get(0));
			System.out.println(list.get(1));

		} catch (NoSuchMethodException |InvocationTargetException | IllegalAccessException|IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}

	public void fun5_1() {
		int[] temp = { 1, 2, 3, 4, 5 };
		Class<?> demo = temp.getClass().getComponentType();
		System.out.println("数组类型： " + demo.getName());
		System.out.println("数组长度  " + Array.getLength(temp));
		System.out.println("数组的第一个元素: " + Array.get(temp, 0));
		Array.set(temp, 0, 100);
		System.out.println("修改之后数组第一个元素为： " + Array.get(temp, 0));
	}

	public void fun5_2() {
		int[] temp = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int[] newTemp = (int[]) arrayInc(temp, 15);
		print(newTemp);
		String[] atr = { "a", "b", "c" };
		String[] str1 = (String[]) arrayInc(atr, 8);
		print(str1);
	}

	public static Object arrayInc(Object obj, int len) {
		Class<?> arr = obj.getClass().getComponentType();
		Object newArr = Array.newInstance(arr, len);
		int co = Array.getLength(obj);
		System.arraycopy(obj, 0, newArr, 0, co);// 这是数组拷贝最块的函数了
		return newArr;
	}

	public static void print(Object obj) {
		Class<?> c = obj.getClass();
		if (!c.isArray()) {
			return;
		}
		System.out.println("数组长度为： " + Array.getLength(obj));
		for (int i = 0; i < Array.getLength(obj); i++) {
			System.out.print(Array.get(obj, i) + " ");
		}
		System.out.println();
	}

	// 反射机制的动态代理
	public void fun6() {
		MyInvocationHandler demo = new MyInvocationHandler();
		Subject sub = (Subject) demo.bind(new student());
		String info = sub.say("Rollen", 20);
		System.out.println(info);

		// student s= new student();
		// String info1 = s.say("Rollen", 20);
		// System.out.println(info1);

	}

	
	
}
